import { Component, Input, OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { ThreadsVo } from 'src/app/model/threads-vo';
import { concatMap, map } from 'rxjs/operators';
import { ActivatedRoute } from '@angular/router';
import { ReplyService } from 'src/app/services/reply.service';
import { ReplyCollectMemberVo } from 'src/app/model/reply-collect-member-vo';
import { HttpErrorResponse } from '@angular/common/http';
import { ReplyMoodVo } from 'src/app/model/reply-mood-vo';
import { ReplyMoodActionRecord } from 'src/app/model/reply-mood-action-record';
import { MemberStorageService } from 'src/app/services/member-storage.service';
import { UtilService } from 'src/app/services/util.service';
import { MemberVo } from 'src/app/model/member-vo';
import { ScrollPageResult } from 'src/app/model/scroll-page-result';

@Component({
  selector: 'app-reply-infinite-scroll-list',
  templateUrl: './reply-infinite-scroll-list.component.html',
  styles: [``]
})
/**
 * 话题内容页中回复分页
 * @constructor
 */
export class ReplyInfiniteScrollListComponent implements OnInit {
  @Input('threads')
  public threads!: ThreadsVo;
  //过滤楼主(0不过滤)(>0过滤)
  @Input('filterAuthor')
  public filterMaster!: number;
  //回复的排序类型,升序(0),降序(1)
  @Input('sortCategory')
  public sortCategory!: number;
  //当前页码值
  @Input('page')
  public page!: number;
  //每页显示的数量
  @Input('pageSize')
  public pageSize!: number;
  @Input('ipAddr')
  public ipAddr!: string;
  @Input('token')
  public token!: string;
  public items: ReplyCollectMemberVo[] = [];
  public hasNext: boolean = false;
  //当前的URL,用以浏览历史:window.history.pushState
  private url: string = '#';
  //切换Tab时使用! 回复的类型,所有(all),仅看楼主(master)
  private replyCategory!: string;
  //切换Tab时使用! 回复的排序类型,升序(asc),降序(desc)
  private replySort: string = 'asc';
  private replyMoodCollect: ReplyMoodVo[] = [];

  //滚动到底部加载数据
  constructor(
    private location: Location,
    private activatedRoute: ActivatedRoute,
    private replyService: ReplyService,
    private memberStorage: MemberStorageService,
    private util: UtilService) {
    this.activatedRoute.url.pipe(map(s => s.join('/'))).subscribe(res => {
      this.url = '/' + res;
    });
  }

  ngOnInit(): void {
    this.replyCategory = (this.filterMaster > 0) ? 'master' : 'all';
    this.replySort = this.sortCategory === 1 ? 'desc' : 'asc';
    this.getDate();
  }

  //底部的点击加载更多,后期会替换为:自动加载
  public anymore(event: Event): void {
    this.page += 1;
    this.getDate();
    this.location.replaceState(this.url, 'author=' + this.filterMaster + '&sort=' + this.sortCategory + '&p=' + this.page + '&s=' + this.pageSize);
  }

  //加载指定页码的数据
  private getDate(): void {
    this.replyService.getAll(this.threads.id, this.filterMaster ?? 0, '640x360', this.page, this.pageSize, this.sortCategory).pipe(map(epr => {
      return { result: epr.result, hasNext: epr.total > epr.page * epr.size } as ScrollPageResult<ReplyCollectMemberVo>;
    })).pipe(
      concatMap(
        (spr: ScrollPageResult<ReplyCollectMemberVo>) => {
          const postsIds: number[] = spr.result.map(rcm => rcm.replyVo.id);
          return this.replyService.getMultiMoodRecords(this.threads.id, postsIds).pipe(map(moodata => {
            return { moodrs: moodata, data: spr };
          }))
        }))
      .subscribe({
        next: response => {
          const rs: { moodrs: ReplyMoodVo[], data: ScrollPageResult<ReplyCollectMemberVo> } = response;
          this.replyMoodCollect = rs.moodrs;
          //计算结果
          this.items = rs.data.result;
          this.hasNext = rs.data.hasNext;
        },
        error: err => {
          let em: string = '';
          if (err instanceof HttpErrorResponse) {
            if (err.error instanceof ErrorEvent) {
              em = err.error.message;
            } else {
              em = err.error;
            }
          } else if (err instanceof Error) {
            em = err.message;
          } else { em = err; }
          console.log('[ReplyInfinite-CTL]reply query error ' + em);
        },
        complete: () => {
          console.log('[ReplyInfinite-CTL]reply query Completed');
        }
      });
  }

  public getMoodRecord(postsId: number): ReplyMoodVo {
    let rmv: ReplyMoodVo | undefined = this.replyMoodCollect.find(ele => ele.reply === postsId);
    if (!rmv) {
      //不存时塑造一个空的
      const tmp: ReplyMoodVo = { threads: this.threads.id, reply: postsId, likes: 0, hates: 0 };
      //不填充后续的操作无法继续(赞|跃点击时计数更新)
      this.replyMoodCollect.push(tmp);
      //将空的实例返回
      rmv = tmp;
    }
    return rmv;
  }

  //切换标签
  public toggleTab(category: string): void {
    if (!category) {
      return;
    }
    if (this.replyCategory === category) {
      return;
    }
    //重置分类
    this.replyCategory = category;
    this.filterMaster = (category === 'master') ? this.threads.member : 0;
    //重置页码
    this.page = 1;
    //重新拉取数据
    this.getDate();
    this.location.replaceState(this.url, 'author=' + this.filterMaster + '&sort=' + this.sortCategory + '&p=' + this.page + '&s=' + this.pageSize);
  }

  //切换排序
  public toggleSort(sortVal: string): void {
    if (!sortVal) {
      return;
    }
    if (this.replySort === sortVal) {
      return;
    }
    //重置分类
    this.replySort = sortVal;
    this.sortCategory = (sortVal === 'desc') ? 1 : 0;
    //重置页码
    this.page = 1;
    //重新拉取数据
    this.getDate();
    this.location.replaceState(this.url, 'author=' + this.filterMaster + '&sort=' + this.sortCategory + '&p=' + this.page + '&s=' + this.pageSize);
  }

  //追加喜好记录
  public addMoodRecord(moodRecord: ReplyMoodActionRecord): void {
    const tmpMember: MemberVo | null = this.memberStorage.get();
    if (null === tmpMember) {
      this.util.alertError('暂不支持游客进行喜好操作');
      return;
    }

    //REST API
    this.replyService.toggleMoode(
      moodRecord.reply,
      moodRecord.threads,
      moodRecord.value ? 1 : 2,
      tmpMember?.id ?? 0,
      tmpMember?.nickname ?? 'guest',
      this.token,
      this.ipAddr).subscribe({
        next: response => {
          //是增是减
          let rs: string = response ?? 'OK';
          this.moodCounterAsync(moodRecord, rs);
        },
        error: err => {
          let em: string = '';
          if (err instanceof HttpErrorResponse) {
            if (err.error instanceof ErrorEvent) {
              em = err.error.message;
            } else {
              em = (err.status == 417) ? '操作失败' : err.error;
            }
          }
          if (err instanceof Error) {
            em = err.message;
          } else { em = err; }
          this.util.alertError(em);
          console.log('[ReplyInfinite-CTL]toggle Mood error ' + em);
        },
        complete: () => { console.log('[ReplyInfinite-CTL]toggle Mood Completed'); }
      });
  }

  private moodCounterAsync(moodRecord: ReplyMoodActionRecord, result: string): void {
    this.replyMoodCollect.forEach(rmv => {
      if (rmv.reply === moodRecord.reply) {
        if (result === 'ADD') {
          if (moodRecord.value) { //赞
            rmv.likes += 1;
          } else { //踩
            rmv.hates += 1;
          }
        }
        if (result === 'DEL') {
          if (moodRecord.value) {
            rmv.likes -= 1;
          } else {
            rmv.hates -= 1;
          }
        }
      }
    });
  }
}
